﻿using ServiceContrack;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Services
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]//此处定义生命周期。所有客户端的会话都是由该类的实例处理的。percall就是每次呼叫都实例化一个，通信结束关闭。perseesion就是一个会话一个，从客户端连接上整一个，然后等客户端离开，释放。signle就是永远就一个。此处不比纠结，除非对特殊需求，都是persession
    public class CalculatorServices : ICalculatorDuplex
    {
        static int index;
        double result;
        ICalculatorDuplexCallback callback = null;

        public CalculatorServices()
        {
            Console.WriteLine(string.Format("会话{0} 开始", index++));
            result = 0;
            callback = OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();

            callback.Notify(new NotifyData() { NotifyMsg = "你好" });
        }

        public void AddTo(double n)
        {
            Console.WriteLine(string.Format("会话{0} 累加：{1}", index, n));
            result += n;
            
            //ThreadPool.QueueUserWorkItem(//此种方法对于频繁且对性能有需求的任务会行为诡异，虽然执行顺序合理，但并行性能基本可以当做空气
            //    c => 
            //    { 
            //        Thread.Sleep(3000);
            //        callback.Equals(Convert.ToDouble(c));
            //        Console.WriteLine(string.Format("会话{0} 发送加结果：{1}", index, Convert.ToDouble(c)));
            //    }, result);

            //Thread.Sleep(3000);
            //callback.Equals(result);
            AutoResetEvent wait = new AutoResetEvent(false);
            ThreadPool.RegisterWaitForSingleObject(wait,//此种方法，由于不透明且略带随机性的线程调度，执行顺序会略显诡异，但并行性能较高
                (c, t) =>
                {
                    callback.Equals(Convert.ToDouble(c));
                    Console.WriteLine(string.Format("会话{0} 发送加结果：{1}", index, Convert.ToDouble(c)));
                }, result, 3000, true);
            Console.WriteLine(string.Format("会话{0} 累加结束", index));
        }

        public double Multy(double a, double b)
        {
            Console.WriteLine(string.Format("会话{0} 乘：{1} * {2} ", index, a, b));
            double res = a * b;
            Console.WriteLine(string.Format("会话{0} 发送乘结果：{1}", index, res));


            return res;            
        }
    }
}
